
package fmu.pi.view.draw.old;

import fmu.pi.model.bean.Movimentacao;
import fmu.pi.model.bean.Conta;
import fmu.pi.model.bean.Cartao;
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.HBox; 
import javafx.event.EventHandler; 
import javafx.event.ActionEvent; 
import javafx.scene.control.TableView; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TextField; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.control.ListView; 
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.util.ArrayList; 
import javafx.geometry.Pos;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import fmu.pi.view.handler.HandlerView;
import java.text.ParseException;
import javafx.scene.input.MouseEvent;
import java.text.SimpleDateFormat; 
import java.util.Calendar;
import java.util.Date; 
import java.util.GregorianCalendar;
import javafx.scene.control.*;
import javax.swing.JOptionPane;

public class PaneMovimentacao extends BorderPane
{
    private TableView tableBoletos; //tabela de movimentação 
    private TextField dataInicialTextField; //boletos apartir da data incial 
    private TextField dataFinalTextField; //boletos até a data final
    private TextField dataDeLancamentoTextField; //data de lançamento das contas; 
    private TextField valorTextField; //valor do boleto
    private TextField sequenciaTextField; // sequencia a qual o boleto será exibido
    private TextField observacaoTextField; // alguma descrição sobre o boleto
    private Button estimaButton; //botão para estimar um período
    private Button salvaButton; //botão para salvar novo boleto
    private Button updateButton; //altera movimentação
    private Button deletButton; // apaga movimentação
    private Button cancelaButton; //cancela update
    private ListView<Conta> contaListView; // lista de conta para ser veinculada a um boleto
    private ListView<Cartao> cardListView; // lista de cartão para ser veinculado a um boleto
    private HandlerView handler; //classe para tratamento de eventos
    private Cartao cardSelected; //cartão selecionado na cardListView
    private Conta contaSelected; //conta selecionado na contaListView
    private Movimentacao movSelected; //movimentação selecionada na tabela 
    private String dataInicialStr; //data apartir daqui
    private String dataFinalStr; //data até aqui
    private SimpleDateFormat dateFormat; 
    
    //construtor
    public PaneMovimentacao()
    {
        dataCorrente(); //verifica a data e mes e ano atual para iniciar a tabela
        initPane(); 
    }
    
    //inicia o painel
    private void initPane()
    {
        try
        {  
            dateFormat = new SimpleDateFormat("dd/MM/yyyy");
            handler = new HandlerView();
            Date first = dateFormat.parse(dataInicialStr);
            Date last = dateFormat.parse(dataFinalStr); 
            handler.geraExtrato(first, last); 
            setCenter(pane((ArrayList<Movimentacao>)handler.getMovList()));
        }
        catch(ParseException exception)
        {
            exception.printStackTrace(); 
            System.out.println("Erro: " + exception.getMessage()); 
        }
        
    }
    
    //configura a posição de cada componente no painel
    private BorderPane pane(ArrayList<Movimentacao> movs)
    {
        BorderPane pane = new BorderPane();  
        tableBoletos = createTableBoleto(movs); 
        
        HBox boxCenter = new HBox(); 
        boxCenter.setAlignment(Pos.CENTER);
        boxCenter.getChildren().add(tableBoletos); 
        
        pane.setTop(formEstimaData()); 
        pane.setCenter(tableBoletos); 
        pane.setBottom(formMovimentacao());
        
        return pane; 
    }
    
    //cria a tabela movimentação
    private TableView createTableBoleto(ArrayList<Movimentacao> movs)
    {
        TableView table = new TableView(); 
        table.setMaxSize(640, 200);
        
        ObservableList listMovimentacao = 
                FXCollections.observableArrayList(movs); 
        
        TableColumn valorColumn = new TableColumn("Valor");
        valorColumn.setCellValueFactory(
                new PropertyValueFactory<Movimentacao,
                String>("valor"));
        
        TableColumn dataColumn = new TableColumn("Data"); 
        dataColumn.setCellValueFactory(
                new PropertyValueFactory<Movimentacao,
                String>("dataPagamento")); 
        
        TableColumn observacaoColumn = new TableColumn("Observaçao");
        observacaoColumn.setCellValueFactory(
                new PropertyValueFactory<Movimentacao,
                String>("observacao")); 
        
        TableColumn sequenciaColumn = new TableColumn("Sequencia"); 
        sequenciaColumn.setCellValueFactory(
                new PropertyValueFactory<Movimentacao,
                String>("sequencia"));
        
        TableColumn contaColumn = new TableColumn("Conta"); 
        contaColumn.setCellValueFactory(
                new PropertyValueFactory<Movimentacao, String>("nomeConta")); 
        
        TableColumn saldoColumn = new TableColumn("Saldo"); 
        saldoColumn.setCellValueFactory(
                new PropertyValueFactory<Movimentacao, String>("saldo"));
        
        TableColumn creditoColumn = new TableColumn("Credito"); 
        creditoColumn.setCellValueFactory(
                new PropertyValueFactory<Movimentacao, String>("credito")); 
        
        TableColumn debitoColumn = new TableColumn("Debito"); 
        debitoColumn.setCellValueFactory(
                new PropertyValueFactory<Movimentacao, String>("debito")); 
        
        table.getColumns().addAll(dataColumn, contaColumn, 
                sequenciaColumn, valorColumn, creditoColumn, debitoColumn,
                saldoColumn, observacaoColumn); 
        
        table.setItems(listMovimentacao); 
        table.setOnMouseClicked(new TableHandler()); 
        
        return table; 
    }
     
    //cria uma lista de conta
    private ListView createListConta()
    {
        ListView<Conta> contas = new ListView<Conta>(); 
        contas.setMaxSize(150, 40); 
        
        ObservableList listConta = 
                FXCollections.observableArrayList(handler.getAccountList()); 
           
        contas.setItems(listConta); 
        
        return contas; 
    }
    
    //cria uma lista de cartões
    private ListView createListCartao()
    {
        ListView<Cartao> cards = new ListView<Cartao>();
        cards.setMaxSize(120, 30); 
        
        ObservableList listCard = FXCollections.observableArrayList(handler.getCardList()); 
        
        cards.setItems(listCard);  
        
        return cards; 
    }
    
    //cria um grid para informações da movimentação
    private HBox formMovimentacao()
    {
        HBox boxSul = new HBox(); 
        boxSul.setAlignment(Pos.TOP_CENTER);
        
        GridPane grid = new GridPane(); 
        grid.setHgap(5); 
        grid.setVgap(5); 
        
        Date date = new Date(); 
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); 
        
        //Edita as dimensões da tabela
        for(int a = 0; a < 3; a++)
        {
            grid.add(new Rectangle(150, 40, Color.TRANSPARENT), a, 0);
            
            for(int b = 1; b < 4; b++)
                grid.add(new Rectangle(150, 40, Color.TRANSPARENT), a, b); 
        }
        
        Label contaLabel = new Label(); 
        contaLabel.setText("Conta"); 
        contaLabel.setFont(Font.font("Ariel Black", 15)); 
        contaLabel.setTextFill(Color.BLUE); 
        grid.add(contaLabel, 0, 0); 
        
        Label valorLabel = new Label(); 
        valorLabel.setText("Valor"); 
        valorLabel.setFont(Font.font("Ariel Black", 15)); 
        valorLabel.setTextFill(Color.BLUE); 
        grid.add(valorLabel, 1, 0); 
        
        Label dataLabel = new Label(); 
        dataLabel.setText("Data"); 
        dataLabel.setFont(Font.font("Ariel Black", 15)); 
        dataLabel.setTextFill(Color.BLUE); 
        grid.add(dataLabel, 2, 0); 
        
        Label sequenciaLabel = new Label(); 
        sequenciaLabel.setText("Sequencia"); 
        sequenciaLabel.setFont(Font.font("Ariel Black", 15)); 
        sequenciaLabel.setTextFill(Color.BLUE); 
        grid.add(sequenciaLabel, 0, 2); 
        
        Label obsLabel = new Label(); 
        obsLabel.setText("Observação"); 
        obsLabel.setFont(Font.font("Ariel Black", 15)); 
        obsLabel.setTextFill(Color.BLUE); 
        grid.add(obsLabel, 1, 2); 
        
        Label cardLabel = new Label(); 
        cardLabel.setText("Cartão"); 
        cardLabel.setFont(Font.font("Ariel Black", 15));
        cardLabel.setTextFill(Color.BLUE); 
        grid.add(cardLabel, 2, 2); 
        
        valorTextField = new TextField();
        valorTextField.setMaxSize(Double.MAX_VALUE, 30); 
        valorTextField.setText(""); 
        grid.add(valorTextField, 1, 1); 
                
        dataDeLancamentoTextField = new TextField();
        dataDeLancamentoTextField.setMaxSize(Double.MAX_VALUE, 30);
        dataDeLancamentoTextField.setText(dateFormat.format(date)); 
        grid.add(dataDeLancamentoTextField, 2, 1); 
        
        sequenciaTextField = new TextField(); 
        sequenciaTextField.setMaxSize(Double.MAX_VALUE, 30); 
        sequenciaTextField.setText("500");
        grid.add(sequenciaTextField, 0, 3); 
        
        observacaoTextField = new TextField(); 
        observacaoTextField.setMaxSize(Double.MAX_VALUE, 30);
        observacaoTextField.setText(""); 
        grid.add(observacaoTextField, 1, 3);
        
        salvaButton = new Button();
        salvaButton.setText("Salvar"); 
        salvaButton.setMaxSize(80, 30); 
        salvaButton.setOnAction(new SaveButtonHandler()); 
        grid.add(salvaButton, 3, 1);
        
        deletButton = new Button(); 
        deletButton.setText("Apagar"); 
        deletButton.setMaxSize(80, 30); 
        deletButton.setOnAction(new DeletButtonHandler()); 
        grid.add(deletButton, 4, 1); 
        
        updateButton = new Button(); 
        updateButton.setText("Alterar"); 
        updateButton.setMaxSize(80, 30); 
        updateButton.setOnAction(new UpdateButtonHandler());
        updateButton.setVisible(false); 
        grid.add(updateButton, 3, 3); 
        
        cancelaButton = new Button(); 
        cancelaButton.setText("Cancela"); 
        cancelaButton.setMaxSize(80, 30); 
        cancelaButton.setOnAction(new CancelButtonHandler());
        cancelaButton.setVisible(false); 
        grid.add(cancelaButton, 4, 3); 
        
        contaListView = createListConta(); 
        contaListView.setOnMouseClicked(new EventHandler<MouseEvent>()
        {
            @Override
            public void handle(MouseEvent event)
            {
                contaSelected = (Conta) 
                        contaListView.getSelectionModel().getSelectedItem(); 
            }
        });
        grid.add(contaListView, 0, 1); 
        
        cardListView = createListCartao(); 
        cardListView.setOnMouseClicked(new EventHandler<MouseEvent>()
        {
            @Override
            public void handle(MouseEvent event)
            {
                cardSelected = (Cartao)
                        cardListView.getSelectionModel().getSelectedItem(); 
            }
        });
        grid.add(cardListView, 2, 3); 
        
        boxSul.getChildren().add(grid); 
        
        return boxSul; 
    }
    
    private HBox formEstimaData()
    {
        HBox box = new HBox(); 
        box.setSpacing(15); 
        box.setAlignment(Pos.BOTTOM_CENTER); 
    
        GridPane grid = new GridPane(); 
        grid.setHgap(10); 
        grid.setVgap(10); 
        
        for(int a = 0; a < 3; a++)
        {
            grid.add(new Rectangle(100, 30, Color.TRANSPARENT), a, 0);
            
            for(int b = 1; b < 2; b++)
                grid.add(new Rectangle(100, 30, Color.TRANSPARENT), a, b);
        }
        
        Label dataInicialLabel = new Label(); 
        dataInicialLabel.setText("Data Inicial"); 
        dataInicialLabel.setFont(Font.font("Ariel Black", 15)); 
        dataInicialLabel.setTextFill(Color.BLUE); 
        grid.add(dataInicialLabel, 0, 0); 
        
        Label dataFinalLabel = new Label(); 
        dataFinalLabel.setText("Data Final"); 
        dataFinalLabel.setFont(Font.font("Ariel Black", 15)); 
        dataFinalLabel.setTextFill(Color.BLUE);
        grid.add(dataFinalLabel, 1, 0); 
        
        
        dataInicialTextField = new TextField(); 
        dataInicialTextField.setText(dataInicialStr); 
        dataInicialTextField.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
        grid.add(dataInicialTextField, 0, 1); 
        
        dataFinalTextField = new TextField(); 
        dataFinalTextField.setText(dataFinalStr); 
        dataFinalTextField.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); 
        grid.add(dataFinalTextField, 1, 1); 
        
        estimaButton = new Button(); 
        estimaButton.setText("Estimar"); 
        estimaButton.setMaxSize(80, 22); 
        estimaButton.setOnAction(new EventHandler<ActionEvent>()
        {
            @Override
            public void handle(ActionEvent event)
            {   
                try
                {
                    SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
                    dataInicialStr = dataInicialTextField.getText(); 
                    dataFinalStr = dataFinalTextField.getText(); 
                    Date first = format.parse(dataInicialStr);
                    Date last = format.parse(dataFinalStr);
                    handler.geraExtrato(first, last); 
                    
                    setCenter(pane((ArrayList<Movimentacao>)handler.getMovList())); 
                }
                catch(ParseException exception)
                {
                    exception.printStackTrace(); 
                    System.err.println(
                            "Erro ao converter data... Tela Movimentação");
                }
            }
        });
        grid.add(estimaButton, 2, 1); 
        
        box.getChildren().add(grid); 
        
        return box; 
    }
    
    //usa a data atual para iniciar a tabela
    private void dataCorrente()
    {
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); 
        Calendar cal = Calendar.getInstance();
        Integer mesAtual = cal.get(Calendar.MONTH) + 1;  //mês atual
        Integer firstDay = 1;  //primeiro dia do mês
        Integer ano = cal.get(Calendar.YEAR); //ano atual
        Integer lastDay = validaMes(mesAtual, ano); //verifica se o mes é de 28, 29, 30 ou 31 dias.
        dataInicialStr = String.format("%d/%d/%d", firstDay, mesAtual, ano); 
        dataFinalStr = String.format("%d/%d/%d", lastDay, mesAtual, ano);
    }
    
    //valida o mes
    private Integer validaMes(Integer mes, Integer ano)
    {
        Integer finalDay = 31;
 
        switch(mes)
        {
            case 1: finalDay = 31;//janeiro
                break; 
            case 2: finalDay = (new GregorianCalendar().isLeapYear(ano))?29 : 28; 
                break; //fevereiro
            case 3: finalDay = 31; //março
                break; 
            case 4: finalDay = 30;//abril
                break; 
            case 5: finalDay = 31; //maio    
                break; 
            case 6: finalDay = 30; // junho
                break;
            case 7: finalDay = 31; //julho
                break; 
            case 8: finalDay = 31; //agosto
                break; 
            case 9: finalDay = 30; //setembro
                break; 
            case 10: finalDay = 31; //outubro
                break; 
            case 11: finalDay = 30; //novembro
                break; 
            case 12: finalDay = 31; //dezembro
                break; 
        }
       
        return finalDay; 
    }
  
    private class TableHandler implements EventHandler<MouseEvent>
    {
        @Override
        public void handle(MouseEvent event)
        {
            try
            {
                movSelected = (Movimentacao)
                        tableBoletos.getSelectionModel().getSelectedItem();
                if(movSelected != null)
                {
                    valorTextField.setText(String.valueOf(movSelected.getValor())); 
                    dataDeLancamentoTextField.setText(movSelected.getDataPagamento()); 
                    sequenciaTextField.setText(String.valueOf(movSelected.getSequencia()));
                    observacaoTextField.setText(movSelected.getObservacao());
                    updateButton.setVisible(true); 
                    cancelaButton.setVisible(true);
                }
            }
            catch(NullPointerException exception)
            {
                exception.printStackTrace(); 
            }
            catch(Exception exception)
            {
                exception.printStackTrace(); 
            }
        }
    }
    
    private Boolean validaForm()
    {
        if((contaSelected != null) && (!valorTextField.getText().equals(""))
                    &&(!dataDeLancamentoTextField.getText().equals("")))
            return true; 
        
        else
            return false; 
    }
    //trata evento do botão save
    private class SaveButtonHandler implements EventHandler<ActionEvent>
    {
        @Override
        public void handle(ActionEvent event)
        {
            Integer result; 
            Boolean sentinela = true;
            
            if(validaForm())
            {
                Movimentacao mov = new Movimentacao();    
                Date d; 
                
                try
                {
                    do
                    {
                        mov.setValor(Float.parseFloat(valorTextField.getText()));
                        mov.setIdConta(contaSelected.getIdConta()); 
                        if(cardSelected != null)
                            mov.setIdCartao(cardSelected.getIdCard());
                        else
                            mov.setIdCartao(0); 
                        
                        if(!sequenciaTextField.getText().equals(""))
                            mov.setSequencia(Integer.parseInt(
                                    sequenciaTextField.getText()));
                        else
                            mov.setSequencia(500); 
                        
                        if(contaSelected.getTipo().equals("receber"))
                        {
                            mov.setCredito(Float.parseFloat(valorTextField.getText()));
                            mov.setDebito(0f); 
                        }
                        else
                            if(contaSelected.getTipo().equals("pagar"))
                            {
                                mov.setDebito((
                                        Float.parseFloat(valorTextField.getText())) *-1);
                                mov.setCredito(0f); 
                            }
                        mov.setObservacao(observacaoTextField.getText());
                        d = dateFormat.parse(dataDeLancamentoTextField.getText()); //valida a data
                        mov.setDataPagamento(dateFormat.format(d));
                        mov.setNomeConta(contaSelected.getNome()); 
                        sentinela = false; 
                        
                    }while(sentinela);
                }
                catch(NumberFormatException exception)
                {
                    System.err.println("Erro ao converter número"); 
                    JOptionPane.showMessageDialog(null, 
                            "Preencha os campos corretamente"); 
                }
                catch(ParseException exception)
                {
                    System.err.println("Erro ao validar data."); 
                    exception.printStackTrace(); 
                }
                
                result = handler.updateTables(mov,"insert");
                
                if(true)
                {
                    JOptionPane.showMessageDialog(null, 
                            "Monvimentação inserida com sucesso.");  
                    initPane(); 
                }
            }
            else
                JOptionPane.showMessageDialog(null, "Preencha todos os dados");
             
        }
    }
    
    private class DeletButtonHandler implements EventHandler<ActionEvent>
    {
        @Override
        public void handle(ActionEvent event)
        {
            Integer result = 0; 
            
            result = handler.updateTables(movSelected, "delet");
            
            if(result > 0)
            {
                JOptionPane.showMessageDialog(null, 
                        "Item apagado com sucesso.");
                initPane(); 
            }
            else
                JOptionPane.showMessageDialog(null, 
                        "Erro ao apagar item"); 
        }
    }
    
    private class UpdateButtonHandler implements EventHandler<ActionEvent>
    {
        @Override
        public void handle(ActionEvent event)
        {
            Integer result; 
            Boolean sentinela; 
            
            if(validaForm())
            {   
                Date d;    
                try
                {
                    do
                    {
                        movSelected.setValor(Float.parseFloat(valorTextField.getText()));
                        movSelected.setIdConta(contaSelected.getIdConta()); 
                        if(cardSelected != null)    
                            movSelected.setIdCartao(cardSelected.getIdCard());
                        else
                            movSelected.setIdCartao(0); 
                        
                        if(!sequenciaTextField.getText().equals(""))
                            movSelected.setSequencia(Integer.parseInt(
                                    sequenciaTextField.getText()));
                        else
                            movSelected.setSequencia(500); 
                        
                        if(contaSelected.getTipo().equals("receber"))
                        {
                            movSelected.setCredito(Float.parseFloat(valorTextField.getText()));
                            movSelected.setDebito(0f); 
                        }
                        else
                            if(contaSelected.getTipo().equals("pagar"))
                            {
                                movSelected.setDebito((
                                        Float.parseFloat(valorTextField.getText())) *-1);
                                movSelected.setCredito(0f); 
                            }
                        movSelected.setObservacao(observacaoTextField.getText());
                        d = dateFormat.parse(dataDeLancamentoTextField.getText()); //valida a data
                        movSelected.setDataPagamento(dateFormat.format(d));
                        movSelected.setNomeConta(contaSelected.getNome());
                        sentinela = false; 
                        
                    }while(sentinela);
                }
                catch(NumberFormatException exception)
                {
                    JOptionPane.showMessageDialog(null, 
                            "Preencha os campos corretamente"); 
                }
                catch(ParseException exception)
                {
                    System.err.println("Erro ao validar data."); 
                    exception.printStackTrace(); 
                }
                
                result = handler.updateTables(movSelected,"update");
                
                if(result > 0)
                {
                    JOptionPane.showMessageDialog(null, 
                            "Monvimentação alterada com sucesso.");
                    updateButton.setVisible(false); 
                    cancelaButton.setVisible(false); 
                    initPane(); 
                }
                else
                    JOptionPane.showMessageDialog(null, 
                            "Erro ao efetuar operação no banco de dados."); 
            }
            else
                JOptionPane.showMessageDialog(null, "Preencha todos os dados");
            }
        
    }
    
    private class CancelButtonHandler implements EventHandler<ActionEvent>
    {
        @Override
        public void handle(ActionEvent event)
        {
            cancelaButton.setVisible(false); 
            updateButton.setVisible(false); 
            salvaButton.setVisible(true); 
            deletButton.setVisible(true); 
            valorTextField.setText(""); 
            sequenciaTextField.setText("500"); 
            dataDeLancamentoTextField.setText(dateFormat.format(new Date())); 
            observacaoTextField.setText(""); 
        }
    }
}

